<template>
  <el-main>
    <!-- 新增按钮 -->
    <el-form size="small">
      <el-form-item>
        <el-button v-permission="['sys:sysMenuList:add']" type="primary" icon="el-icon-plus" @click="addBtn">新增</el-button>
      </el-form-item>
    </el-form>
    <el-table
      :height="tableHeight"
      :data="tableData"
      style="width: 100%;margin-bottom: 20px;"
      row-key="menuId"
      border
      default-expand-all
      :tree-props="{children: 'children', hasChildren: 'hasChildren'}"
    >
      <el-table-column
        prop="title"
        label="菜单名称"
      />
      <el-table-column prop="type" label="菜单类型">
        <template slot-scope="scope">
          <el-tag v-if="scope.row.type === '0'">目录</el-tag>
          <el-tag v-if="scope.row.type === '1'" type="success">菜单</el-tag>
          <el-tag v-if="scope.row.type === '2'" type="danger">按钮</el-tag>
        </template>
      </el-table-column>
      <el-table-column
        prop="icon"
        label="菜单图标"
      >
        <template slot-scope="scope">
          <i :class="scope.row.icon" />
        </template>
      </el-table-column>
      <el-table-column
        prop="name"
        label="路由名称"
      />
      <el-table-column
        prop="path"
        label="路由地址"
      />
      <el-table-column
        prop="url"
        label="组件路径"
      />
      <el-table-column
        prop="code"
        label="权限字段"
      />
      <el-table-column
        prop="orderNum"
        label="序号"
      />
      <el-table-column v-if="$checkPermission(['sys:sysMenuList:edit', 'ssys:sysMenuList:delete'])" label="操作" align="center" width="180">
        <template slot-scope="scope">
          <el-button v-permission="['sys:sysMenuList:edit']" type="primary" size="small" icon="el-icon-edit" @click="editBtn(scope.row)">编辑</el-button>
          <el-button v-permission="['sys:sysMenuList:delete']" type="danger" size="small" icon="el-icon-close" @click="deleteBtn(scope.row)">删除</el-button>

        </template>
      </el-table-column>
    </el-table>
    <sys-dialog
      :title="dialog.title"
      :height="dialog.height"
      :visible.sync="dialog.visible"
      :eidth="dialog.width"
      @onClose="onClose"
      @onConfirm="onConfirm"
    >
      <div slot="content">
        <el-form ref="addModel" :model="addModel" :rules="rules" label-width="80px" size="small">
          <el-row>
            <el-col :span="12" :offset="0">
              <el-form-item prop="type" label="菜单类型">
                <el-radio-group v-model="addModel.type">
                  <el-radio :label="'0'">目录</el-radio>
                  <el-radio :label="'1'">菜单</el-radio>
                  <el-radio :label="'2'">按钮</el-radio>
                </el-radio-group>
              </el-form-item>
            </el-col>
          </el-row>
          <el-row>
            <el-col :span="12" :offset="0">
              <el-form-item prop="parentName" label="上级菜单">
                <el-input v-model="addModel.parentName" @click.native="selectParent" />
              </el-form-item></el-col>
            <el-col :span="12" :offset="0">
              <el-form-item prop="title" label="菜单名称">
                <el-input v-model="addModel.title" />
              </el-form-item>
            </el-col>
          </el-row>
          <el-row>
            <el-col :span="12" :offset="0">
              <el-form-item v-if="addModel.type != '2'" label="菜单图标">
                <el-input v-model="addModel.icon" />
              </el-form-item></el-col>
            <el-col :span="12" :offset="0">
              <el-form-item v-if="addModel.type !== '2'" prop="name" label="路由名称">
                <el-input v-model="addModel.name" />
              </el-form-item>
            </el-col>
          </el-row>
          <el-row>
            <el-col :span="12" :offset="0">
              <el-form-item label="菜单序号">
                <el-input v-model="addModel.orderNum" />
              </el-form-item>
            </el-col>
            <el-col :span="12" :offset="0">
              <el-form-item label="权限字段">
                <el-input v-model="addModel.code" />
              </el-form-item></el-col>
          </el-row>
          <el-row>
            <el-col :span="12" :offset="0">
              <el-form-item v-if="addModel.type !== '2'" prop="path" label="路由地址">
                <el-input v-model="addModel.path" />
              </el-form-item></el-col>
            <el-col :span="12" :offset="0">
              <el-form-item v-if="addModel.type === '1'" prop="url" label="组件路径">
                <el-input v-model="addModel.url" />
              </el-form-item>
            </el-col>
          </el-row>

        </el-form>

      </div>
    </sys-dialog>
    <!-- 上级菜单弹框 -->
    <sys-dialog
      :title="parentDialog.title"
      :height="parentDialog.height"
      :visible.sync="parentDialog.visible"
      :width="parentDialog.width"
      @onClose="onParentClose"
      @onConfirm="onParentConfirm"
    >
      <div slot="content">
        <el-tree
          ref="parentData"
          :data="parentData"
          :node-key="menuId"
          :props="defaultProps"
          empty-text="暂无数据"
          :show-checkbox="false"
          :highlight-current="true"
          default-expand-all
          :expand-on-click-node="false"
          @node-click="handleNodeClick"
        >
          <div slot-scope="{node, data}">
            <!-- 如果没有下级显示文档图标 -->
            <span v-if="data.children.length === 0">
              <i style="margin-left: 3px" class="el-icon-document" />
            </span>
            <!-- 如果有下级判断是否展开 -->
            <span v-else @click.stop="openBtn(node)">
              <i
                v-if="node.expanded"
                style="margin-left: 3px"
                class="el-icon-plus"
              />
              <i v-else style="margin-left: 3px" class="el-icon-minus" />
            </span>
            <span style="margin-left: 3px">{{ node.label }}</span>
          </div>
        </el-tree>
      </div>
    </sys-dialog>
  </el-main>

</template>

<script>
import { addMenuApi, deleteMenuApi, editMenuApi, getListApi, getParentListApi } from '@/api/menu'
import SysDialog from '@/components/dialog/SysDialog.vue'
export default {
  components: {
    SysDialog
  },
  data: function() {
    return {
      selectNode: {
        menuId: '',
        title: ''
      },
      defaultProps: {
        children: 'children',
        label: 'title'
      },
      // 上级菜单数据
      parentData: [],
      // 上级菜单弹窗属性
      parentDialog: {
        height: 400,
        width: 300,
        visible: false,
        title: '选择上级菜单'
      },
      // 表单验证规则
      rules: {
        type: [{
          required: true,
          message: '请选择菜单类型',
          trigge: 'blur'
        }],
        parentName: [{
          required: true,
          message: '请选择上级菜单',
          trigge: 'blur'
        }],
        title: [{
          required: true,
          message: '请填写菜单名称',
          trigge: 'blur'
        }],
        name: [{
          required: true,
          message: '请填写路由名称',
          trigge: 'blur'
        }],
        path: [{
          required: true,
          message: '请填写路由地址',
          trigge: 'blur'
        }],
        url: [{
          required: true,
          message: '请填写组件路径',
          trigge: 'blur'
        }]
      },
      // 表单数据
      addModel: {
        editType: '', // 0:新增 1:编辑
        menuId: '',
        type: '',
        parentId: '',
        title: '',
        code: '',
        name: '',
        path: '',
        url: '',
        icon: '',
        parentName: '',
        orderNum: ''
      },
      // 定义弹窗属性
      dialog: {
        height: 260,
        width: 630,
        visible: false,
        title: ''
      },
      // 定义表格属性
      tableHeight: 0,
      // 树形数据
      treeData: [],
      // 表格数据
      tableData: []
    }
  },
  mounted() {
    this.$nextTick(() => {
      this.tableHeight = window.innerHeight - 220
    })
  },
  created() {
    this.getList()
  },
  methods: {
    // 上级部门节点加号和减号点击事件
    openBtn(node) {
      node.expanded = !node.expanded
    },
    // 编辑
    editBtn(row) {
      // 设置弹框属性
      this.dialog.title = '编辑菜单'
      // 清空验证与数据
      if (this.$refs.addModel !== undefined) {
        this.$refs.addModel.resetFields()
        this.$emptyData(this.addModel)
      }
      this.$objCopy(row, this.addModel)
      this.dialog.visible = true
      this.addModel.editType = '1'
    },
    async deleteBtn(row) {
      const confirm = await this.$myconfirm('确定删除该数据吗？')
      if (confirm) {
        const res = await deleteMenuApi({ menuId: row.menuId })
        console.log(res.code)
        if (res && res.code === 200) {
          // 消息提示
          console.log(this)
          this.$message({
            type: 'success',
            message: res.msg
          })
          // 刷新列表
          this.getList()
        }
      }
    },
    // 上级菜单节点点击事件
    handleNodeClick(node) {
      this.selectNode.menuId = node.menuId
      this.selectNode.title = node.title
    },
    async selectParent() {
      // 获取上级菜单数据
      const res = await getParentListApi(null)
      if (res && res.code === 200) {
        this.parentData = res.data
      }
      this.parentDialog.visible = true
    },
    onParentClose() {
      this.parentDialog.visible = false
    },
    onParentConfirm() {
      this.addModel.parentId = this.selectNode.menuId
      this.addModel.parentName = this.selectNode.title
      this.parentDialog.visible = false
    },
    onClose() {
      this.dialog.visible = false
    },
    onConfirm() {
      this.$refs.addModel.validate(async(valid) => {
        if (valid) {
          let res = null
          if (this.addModel.editType === '0') {
            res = await addMenuApi(this.addModel)
          } else {
            res = await editMenuApi(this.addModel)
          }
          if (res && res.code === 200) {
            // 消息提示
            this.$message({
              type: 'success',
              message: res.msg
            })
            // 刷新表格
            this.getList()
          }
        }
      })
      // 关闭弹窗
      this.dialog.visible = false
    },
    // 新增按钮
    addBtn() {
      // 设置弹框属性
      this.dialog.title = '新增菜单'
      // 清空验证与数据
      if (this.$refs.addModel !== undefined) {
        this.$refs.addModel.resetFields()
        this.$emptyData(this.addModel)
      }
      this.dialog.visible = true
      this.addModel.editType = '0'
    },
    // 获取表格数据
    async getList() {
      const res = await getListApi()
      if (res && res.code === 200) {
        this.tableData = res.data
      }
    }
  }

}
</script>

<style lang="scss" scoped>
::v-deep .el-tree {
  // 将每一行设置为相对位置 方便后面的before after使用绝对位置来固定位置
  .el-tree-node {
    position: relative;
    padding-left: 10px;
  }
  // 子集向右偏移，给树线流出距离
  .el-tree-node__children {
    padding-left: 20px;
  }
  // 竖线
  .el-tree-node :last-child:before{
    height: 40px;
  }
  .el-tree > .el-tree-node:before {
    border-left: none;
  }
  .el-tree > .el-tree-node:after {
    border-top: none;
  }
  // 自定义的线的公共部分
  .el-tree-node:before,
  .el-tree-node:after {
    content: '';
    left: -4px;
    position: absolute;
    right: auto;
    border-width: 1px;
  }
  .tree :first-child .el-tree-node:before {
    border-left: none;
  }
  // 竖线
  .el-tree-node:before {
    border-left: 1px dotted #d9d9d9;
    bottom: 0px;
    height: 100%;
    top: -25px;
    width: 1px;
  }
  // 横线
  .el-tree-node:after {
    border-top: 1px dotted #d9d9d9;
    height: 20px;
    top: 14px;
    width: 24px;
  }
  .el-tree-node__expand-icon.is-leaf {
    width: 8px;
  }
  // 去掉自带的展开按钮，一个向下，打开时向右
  .el-tree-node__content>.el-tree-node__expand-icon {
    display: none;
  }
  // 每一行的高度
  .el-tree-node__content {
    line-height: 30px;
    height: 30px;
    padding-left: 10px !important;
  }
  // 去掉最上层的before after 即最上层的连接线
  ::v-deep .el-tree>div {
    &::before {
      display: none;
    }
    &::after {
      display: none;
    }
  }
}

</style>
